package thread;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by Robo on 2020/5/16.
 */
class Mydata{
    volatile int number = 0;
    public void addTo60() {
        this.number = 60;
    }
    void addPlusPlus(){
        this.number++;
    }
    synchronized void addPlusPlusSync(){
        this.number++;
    }

    AtomicInteger aNumber = new AtomicInteger(0);
    void addAtom(){
        aNumber.getAndIncrement();
    }
}

public class VolatileDemo {
    public static void main(String[] args) {
//        seeOk();
        atomNotOk();
    }

    //不保证原子性
    private static void atomNotOk() {
        Mydata mydata = new Mydata();
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    mydata.addPlusPlus();
//                    mydata.addPlusPlusSync();
                    mydata.addAtom();
                }
            }, String.valueOf(i)).start();
        }

        while (Thread.activeCount() > 2) {
            Thread.yield();
        }

        System.out.println(Thread.currentThread().getName() + "\t finally num:" + mydata.number);
        System.out.println(Thread.currentThread().getName() + "\t finally num:" + mydata.aNumber);
    }

    //volatile 可以保证可见性
    private static void seeOk() {
        Mydata mydata = new Mydata();

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\tcome in");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mydata.addTo60();
            System.out.println(Thread.currentThread().getName() + "\tupdate num Value:" + mydata.number);
        },"AAA").start();

        while (mydata.number == 0) {
            // do nothing
        }
        System.out.println(Thread.currentThread().getName() + "\t mission over Value:" + mydata.number);
    }
}
